<template>
  <view class="template-reserve tn-safe-area-inset-bottom">
    <text
      :prop="options"
      :change:prop="renderScript.onChange"
      v-show="false"
    ></text>
    <canvas
      canvas-id="posterCanvas"
      id="posterCanvas"
      style="
        width: 600px;
        height: 1067px;
        position: absolute;
        left: -9999px;
        top: -9999px;
      "
    ></canvas>
    <web-view
      :webview-styles="isIos ? webViewStyle : webViewStyleAnd"
      v-if="currentIndex === 0"
      :src="wvUrl"
      style="z-index: -999"
      @message="message"
      id="my-webview"
      ref="webview"
    ></web-view>
    <galaxy-brand v-if="currentIndex === 1"></galaxy-brand>
    <message ref="message" v-if="currentIndex === 2"></message>
    <mine ref="mine" v-if="currentIndex === 3"></mine>
    <view
      class="custom-tabbar"
      :class="isIos ? 'webIos' : 'webAndroid'"
      v-if="showtabbar"
    >
      <view
        class="tabbar-item"
        v-for="(item, index) in tabbarList"
        :key="index"
        @click="switchTabbar(index)"
      >
        <view class="tabbar-icon">
          <image
            :src="currentIndex === index ? item.inactiveIcon : item.activeIcon"
            class="icon-image"
            :style="{
              width: item.iconSize + 'rpx',
              height: item.iconSize + 'rpx',
            }"
          />
        </view>
        <text
          class="tabbar-text"
          :style="{
            color: currentIndex === index ? activeColor : inactiveColor,
          }"
        >
          {{ item.title }}
        </text>
      </view>
    </view>
  </view>
</template>

<script>
import template_page_mixin from "@/libs/mixin/template_page_mixin.js";
import emoji from "@/plugins/emoji.js";
import GalaxyBrand from "./galaxyBrand/index.vue";
import myVoice from "@/components/self-voice/index.vue";
import Mine from "./mine/mine.vue";
import Message from "./message/index.vue";
import homeIcon from "../static/icon/home-icon.png";
import homeIconFs from "../static/icon/home-icon-f.png";
// import NextCas from "@nextcas/sdk";
// import Record from "@nextcas/voice";
// 在创建 WebView 的页面中添加
const innerAudioContext = uni.createInnerAudioContext();
const recorderManager = uni.getRecorderManager();
var wv;
var currentWebview;
export default {
  name: "TemplateReserve",
  mixins: [template_page_mixin],
  components: {
    myVoice,
    Mine,
    GalaxyBrand,
    Message,
  },
  data() {
    return {
      // tabbar当前被选中的序号
      currentIndex: 10,
      // 自定义底栏对应页面的加载情况
      showtabbar: true,
      webViewStyle: {
        width: "100%",
        height: "90%",
      },
      webViewStyleAnd: {
        width: "100%",
        height: "94%",
      },
      tabbarList: [
        {
          title: "私小理",
          activeIcon: require("../static/icon/home-icon.png"), // 激活状态图片
          inactiveIcon: require("../static/icon/home-icon-f.png"), // 非激活状态图片
          iconSize: 50,
        },
        {
          title: "发现",
          activeIcon: require("../static/icon/fx-icon.png"),
          inactiveIcon: require("../static/icon/fx-icon-f.png"),
          iconSize: 50,
        },
        {
          title: "消息",
          activeIcon: require("../static/icon/message-icon.png"),
          inactiveIcon: require("../static/icon/message-icon-f.png"),
          iconSize: 50,
        },
        {
          title: "我的",
          activeIcon: require("../static/icon/my-icon.png"),
          inactiveIcon: require("../static/icon/my-icon-f.png"),
          iconSize: 50,
        },
      ],
      groupList: [
        {
          src: "/static/logo.png",
        },
        {
          src: "/static/logo.png",
        },
        {
          src: "/static/logo.png",
        },
        {
          src: "/static/logo.png",
        },
        {
          src: "/static/logo.png",
        },
        {
          src: "/static/logo.png",
        },
        {
          src: "/static/logo.png",
        },
        {
          src: "/static/logo.png",
        },
        {
          src: "/static/logo.png",
        },
        {
          src: "/static/logo.png",
        },
        {
          src: "https://resource.tuniaokj.com/images/shop/cup1.jpg",
        },
        {
          src: "https://resource.tuniaokj.com/images/blogger/avatar_4.jpeg",
        },
        {
          src: "https://resource.tuniaokj.com/images/blogger/avatar_3.jpeg",
        },
        {
          src: "https://resource.tuniaokj.com/images/blogger/blogger_beibei.jpg",
        },
        {
          src: "https://resource.tuniaokj.com/images/blogger/avatar_1.jpeg",
        },
        {
          src: "https://resource.tuniaokj.com/images/blogger/avatar_2.jpeg",
        },
        {
          src: "https://resource.tuniaokj.com/images/blogger/avatar_3.jpeg",
        },
        {
          src: "https://resource.tuniaokj.com/images/blogger/avatar_4.jpeg",
        },
        {
          src: "https://resource.tuniaokj.com/images/blogger/blogger_beibei.jpg",
        },
        {
          src: "https://resource.tuniaokj.com/images/blogger/avatar_1.jpeg",
        },
        {
          src: "https://resource.tuniaokj.com/images/blogger/avatar_2.jpeg",
        },
        {
          src: "https://resource.tuniaokj.com/images/blogger/avatar_3.jpeg",
        },
        {
          src: "https://resource.tuniaokj.com/images/blogger/avatar_4.jpeg",
        },
        {
          src: "https://resource.tuniaokj.com/images/blogger/avatar_3.jpeg",
        },
        {
          src: "https://resource.tuniaokj.com/images/blogger/blogger_beibei.jpg",
        },
        {
          src: "https://resource.tuniaokj.com/images/blogger/avatar_1.jpeg",
        },
        {
          src: "https://resource.tuniaokj.com/images/blogger/avatar_2.jpeg",
        },
        {
          src: "https://resource.tuniaokj.com/images/blogger/avatar_3.jpeg",
        },
        {
          src: "https://resource.tuniaokj.com/images/shop/watch1.jpg",
        },
        {
          src: "https://resource.tuniaokj.com/images/blogger/avatar_4.jpeg",
        },
        {
          src: "https://resource.tuniaokj.com/images/blogger/avatar_2.jpeg",
        },
        {
          src: "https://resource.tuniaokj.com/images/blogger/blogger_beibei.jpg",
        },
        {
          src: "https://resource.tuniaokj.com/images/blogger/avatar_1.jpeg",
        },
        {
          src: "https://resource.tuniaokj.com/images/blogger/avatar_2.jpeg",
        },
        {
          src: "https://resource.tuniaokj.com/images/blogger/avatar_3.jpeg",
        },
        {
          src: "https://resource.tuniaokj.com/images/blogger/avatar_4.jpeg",
        },
        {
          src: "https://resource.tuniaokj.com/images/blogger/blogger_beibei.jpg",
        },
        {
          src: "https://resource.tuniaokj.com/images/blogger/avatar_2.jpeg",
        },
        {
          src: "https://resource.tuniaokj.com/images/blogger/blogger_beibei.jpg",
        },
        {
          src: "https://resource.tuniaokj.com/images/blogger/avatar_4.jpeg",
        },
        {
          src: "https://resource.tuniaokj.com/images/blogger/blogger_beibei.jpg",
        },
        {
          src: "https://resource.tuniaokj.com/images/blogger/avatar_1.jpeg",
        },
        {
          src: "https://resource.tuniaokj.com/images/blogger/avatar_2.jpeg",
        },
        {
          src: "https://resource.tuniaokj.com/images/blogger/avatar_4.jpeg",
        },
        {
          src: "https://resource.tuniaokj.com/images/blogger/blogger_beibei.jpg",
        },
        {
          src: "https://resource.tuniaokj.com/images/blogger/avatar_1.jpeg",
        },
        {
          src: "https://resource.tuniaokj.com/images/blogger/avatar_3.jpeg",
        },
      ],
      emojis: [],
      isEdit: true,
      isFocus: false,
      showEmoji: false,
      showFile: false,
      showVoice: false,
      scrollHeight: "auto", // 内容区域高度
      statusBarHeight: 0, // 状态栏高度
      scrollViewId: "", // 滚动到最底部
      voicePlayingId: "", // 正在播放的消息ID
      content: "",
      list: [],
      socketOpen: false,
      socketMsgQueue: [],
      fromUserId: uni.getStorageSync("userId"),
      fromUserFace: uni.getStorageSync("userFace"),
      toUserId: "",
      toUserName: "聊天室",
      tokenInfo: "",
      nextCas: "",
      record: "",
      isVideo: false,
      recording: false,
      inited: false,
      speacking: false,
      loading: true,
      // wvUrl: 'http://11.37.128.189:8080/#/activityPages/map',
      wvUrl: "http://11.37.131.18:8080/#/activityPages/map",
      userInfo: uni.getStorageSync("userInfo") || null,
      loginToken: uni.getStorageSync("loginToken") || "",
      isSpeaking: false,
      zsid: 0,
      setbaseurl: 0,
      clientid: "",
      options: {},
      baseurl: [
        "/work1031/",
        "/work1032/",
        "/work1033/",
        "/work1034/",
        "/work1035/",
        "/work1036/",
        "/work1037/",
        "/work1038/",
        "/work1051/",
        "/work1052/",
        "/work1053/",
        "/work1054/",
        "/work1055/",
        "/work1056/",
        "/work1057/",
        "/work1058/",
        "/work1061/",
        "/work1062/",
        "/work1063/",
        "/work1064/",
        "/work1065/",
        "/work1066/",
        "/work1067/",
        "/work1068/",
        "/work1071/",
        "/work1072/",
        "/work1073/",
        "/work1074/",
        "/work1075/",
        "/work1076/",
        "/work1077/",
        "/work1078/",
        "/work1091/",
        "/work1092/",
        "/work1093/",
        "/work1094/",
        "/work1095/",
        "/work1096/",
        "/work1097/",
        "/work1098/",
      ],
      appSecret: "",
      userid: "", // 用户id
      isIos: false,
      isMeeting: false,
      meetingLv: 0,
      scheduleobj: null,
      userDetail: null, // 用于存储用户信息
      ishome: 1,
      isSharePosterVisible: false,
    };
  },
  created() {
    if (!this.userid) {
      uni.navigateTo({
        url: "/minePages/login",
      });
      return; // 阻止后续执行
    }
  },
  onLoad(option) {
    let { system } = uni.getSystemInfoSync();
    this.isIos = system.indexOf("iOS") > -1;
    this.appSecret = this.userInfo.bot_appsecret;
    this.userid = this.userInfo.userid;
    this.islogin(this.userid);
    this.getUserInfo(this.userid);
    // 初始化内容高度
    this.setScrollHeight();
    this.requestAndroidPermission();
    // 初始化状态栏高度
    uni.getSystemInfo({
      success: (res) => {
        this.statusBarHeight = res.statusBarHeight;
      },
    });
    this.switchTabbar(0);
    this.wvUrl =
      "http://11.37.131.18:8080/#/activityPages/map?appsecret=" +
      this.appSecret +
      "&userid=" +
      this.userInfo.userid +
      "&formPage=home&invite_code=" +
      this.userInfo.invite_code;
    // this.wvUrl = "http://www.cycyai.com/humanC/#/activityPages/map?appsecret=" + this.appSecret + "&userid=" + this.userInfo.userid + "&formPage=home"
    this.initWebViewSoftinputMode(true);

    const recorderManager = uni.getRecorderManager();
    recorderManager.onError((err) => {
      console.error("recorderManager：" + err);
      // 根据错误信息进行相应的处理
    });

    var that = this;

    // 结束录音
    recorderManager.onStop(function async(res) {
      // date.path = res.tempFilePath  // 这个是录音文件的临时地址
      // date.time = timeLength.value    // 录音时长

      // 上传音频文件到服务器上
      if (!that.isMeeting) {
        uni.uploadFile({
          url: "https://ocr.luyanshidai.com:6501/api/core/user/upload", //仅为示例，非真实的接口地址
          filePath: res.tempFilePath, //  这个是录音文件的临时地址
          name: "file",
          formData: {
            user: "test",
          },
          success: (uploadFileRes) => {
            // console.log("uploadFileRes" + uploadFileRes.data)
            var obj = JSON.parse(uploadFileRes.data);
            if (obj.status == "success") {
              console.log("ask" + obj.data.Info.result[0].text);
              wv.evalJS(
                "document.dispatchEvent(new CustomEvent('message',{detail: {ask:" +
                  JSON.stringify(obj.data.Info.result[0].text) +
                  "}}))"
              );
            }
          },
        });
      } else {
        uni.uploadFile({
          url: "https://ocr.luyanshidai.com:6501/api/core/user/hsasrupload", //仅为示例，非真实的接口地址
          filePath: res.tempFilePath, //  这个是录音文件的临时地址
          name: "file",
          formData: {
            user: "test",
          },
          success: (uploadFileRes) => {
            var obj = JSON.parse(uploadFileRes.data);
            if (obj.status == "success") {
              // var obj2 = JSON.parse(obj.data.Info);
              that.isMeeting = false;
              let formData = {
                appsecret: that.appSecret,
                lfasrid: obj.data.Info,
                meetinglv: that.meetingLv,
                userid: that.userInfo.userid,
              };
              that.$Request
                .getApi("/bot/api/agentcsetlfasr", formData)
                .then((res) => {});
            }
          },
        });
      }
    });

    // this.recorderManager.onStop(res=>{
    // 	this.upload(res.tempFilePath)
    // })

    // 结束播放
    innerAudioContext.onEnded((res) => {
      this.voicePlayingId = "";
    });

    // 设置标题
    uni.setNavigationBarTitle({
      title: option.toUserName,
    });

    // 获取参数
    this.toUserId = this.userInfo.userid;
    this.toUserName = this.userInfo.username;
    this.emojis = emoji;

    // 获取消息记录

    // 监听webSocket消息
    // this.$xbcim.onmessage(data=>{
    // 	// 只接受单聊消息
    // 	if(data.type != 'single') return

    // 	// 处理数据
    // 	data.id = data.extra.id
    // 	data.userFace = data.extra.userFace
    // 	this.list.push(data)
    // 	this.initScrollBar()
    // })

    // this.$Request.getT("/api/core/user/token").then(async (res) => {
    //     if (res.code == 20000) {
    // 		// console.log("nextCas");
    //       this.tokenInfo = res.data.tokenInfo;
    // 		const container = document.getElementById('nextcas');
    // const canvasEle = document.createElement('canvas');
    // container.appendChild(canvasEle);
    // const gl = canvasEle.getContext('webgl');
    // // console.log('Before await');
    // 		this.nextCas = await new NextCas(container, {
    // 		  token: res.data.tokenInfo,
    // 		  actorId: "actor_100256",
    // 		  templateName: "base",
    // 		  avatarId: "avatar_257",
    // 		});
    // // console.log('After await');
    // // this.loading = false;
    //     }
    // });

    // this.$Request.getT("/api/core/user/token").then(async (res) => {
    //     if (res.code == 20000) {
    //       this.tokenInfo = res.data.tokenInfo;
    // 		this.record = new Record(res.data.tokenInfo, "641811add41a3f2f91247af5");
    //     }
    // });
  },
  onShow() {
    this.wvUrl =
      "http://11.37.131.18:8080/#/activityPages/map?appsecret=" +
      this.appSecret +
      "&userid=" +
      this.userid +
      "&formPage=home&invite_code=" +
      this.userInfo.invite_code;
    // this.wvUrl = "http://www.cycyai.com/humanC/#/activityPages/map?appsecret=" + this.appSecret + "&userid=" + this.userid + "&formPage=home";
    var currentWebview = this.$scope.$getAppWebview(); //获取当前页面的webview
    if (
      currentWebview &&
      currentWebview.children() &&
      currentWebview.children()[0]
    ) {
      currentWebview.children()[0].reload(); // 安全调用reload方法
    }
    // var currentWebview = this.$scope.$getAppWebview() //获取当前页面的webvie
    // currentWebview.children()[0].reload() // 如果该方法存在，则可以调用
    this.islogin();
  },
  onReady() {
    this.watchKeyboard();
    // #ifdef APP-PLUS
    // 延迟执行，确保WebView已加载
    setTimeout(() => {
      if (wv) {
        // 重置页面状态
        wv.evalJS(`
			        document.body.scrollTop = 0;
			        document.documentElement.scrollTop = 0;
			        const inputContainer = document.querySelector('.reserve-webview-bottom');
			        const reserveContent = document.querySelector('.reserve-content');
			        if (inputContainer) {
			          inputContainer.style.transform = 'translate3d(0, 0, 0)';
			          reserveContent.style.transform = 'translate3d(0, 0, 0)';
			          document.body.setAttribute('data-keyboard', 'hidden');
			        }
			      `);
      }
    }, 800);
    // #endif
  },
  onHide() {
    // innerAudioContext.stop()
    wv.evalJS(
      "document.dispatchEvent(new CustomEvent('message',{detail: {onhide:1}}))"
    );

    let date = {
      client_id: this.clientid,
    };
    // // let date2 = null;
    this.options = {
      myDate: date,
      url:
        "https://human.cycyai.com:8881" +
        this.baseurl[this.setbaseurl] +
        "imagehuman-unlock-client-id",
    };
    // console.log("onHide")
  },
  onBackPress() {
    if (this.showFile || this.showEmoji) {
      this.showFile = false;
      this.showEmoji = false;
      this.setScrollHeight(0);
      return true;
    }
    return false;
  },
  methods: {
    //获取用户信息
    getUserInfo(userid) {
      this.$Request
        .postApi("/bot/api/agentgetuserinfo", {
          userid: userid,
        })
        .then((res) => {
          if (res.status === 1) {
            this.userDetail = res.data;
            // 更新本地缓存
            uni.setStorageSync("userInfo", res.data);
          } else {
            uni.showToast({
              title: res.message || "获取用户信息失败",
              icon: "none",
            });
          }
        })
        .catch(() => {
          uni.showToast({
            title: "网络错误",
            icon: "none",
          });
        });
    },
    switchTabbar(index) {
      this.currentIndex = index;
      if (index === 1) {
        uni.pageScrollTo({
          scrollTop: 0,
        });
      }
      if (index === 0) {
        recorderManager = uni.getRecorderManager();
        // console.log('recorderManager')
        // console.log(recorderManager)
        recorderManager.onError((err) => {
          console.error("recorderManager：" + err);
          // 根据错误信息进行相应的处理
        });
        // 结束录音
        recorderManager.onStop(function async(res) {
          // date.path = res.tempFilePath  // 这个是录音文件的临时地址
          // date.time = timeLength.value    // 录音时长
          // 上传音频文件到服务器上
          uni.uploadFile({
            url: "https://ocr.luyanshidai.com:6501/api/core/user/upload", //仅为示例，非真实的接口地址
            filePath: res.tempFilePath, //  这个是录音文件的临时地址
            name: "file",
            formData: {
              user: "test",
            },
            success: (uploadFileRes) => {
              // console.log('uploadFileRes' + uploadFileRes.data)
              var obj = JSON.parse(uploadFileRes.data);
              if (obj.status == "success") {
                // console.log('ask' + obj.data.Info.result[0].text)
                wv.evalJS(
                  "document.dispatchEvent(new CustomEvent('message',{detail: {ask:" +
                    JSON.stringify(obj.data.Info.result[0].text) +
                    "}}))"
                );
              }
            },
          });
          // console.log('recorder stop' + JSON.stringify(res))
          // self.voicePath = res.tempFilePath
        });
        // this.recorderManager.onStop(res=>{
        // 	this.upload(res.tempFilePath)
        // })
        // 结束播放
        innerAudioContext.onEnded((res) => {
          this.voicePlayingId = "";
        });
        this.initWebViewSoftinputMode(true);
      }
    },
    watchKeyboard() {
      uni.onKeyboardHeightChange((res) => {
        if (res.height > 0) {
          // 键盘弹起
          this.showtabbar = false;
        } else {
          // 键盘关闭
          this.showtabbar = true;
        }
      });
    },
    initWebViewSoftinputMode(isInit) {
      let { system } = uni.getSystemInfoSync();
      this.isIos = system.indexOf("iOS") > -1;
      const isIosEv = system.indexOf("iOS") > -1;
      setTimeout(() => {
        currentWebview = this.$scope.$getAppWebview(); //获取当前页面的webview
        wv = currentWebview.children()[0]; //获取当前web-view
        if (wv) {
          // 统一设置为 adjustPan 模式，避免页面被压缩
          currentWebview.setStyle({
            webview: {
              softinputMode: "adjustPan", // 修改为 adjustPan
              scrollIndicator: "none",
              bounce: "none",
              hardwareAccelerated: true,
            },
          });

          // 设置WebView子页面样式
          wv.setStyle({
            softinputMode: "adjustPan", // 统一使用 adjustPan
            renderedInViewGroup: true,
            scalable: false,
          });

          // 注入防止闪烁的CSS和JS
          wv.evalJS(`
			        // 添加meta标签控制视口
			        if (!document.querySelector('meta[name="viewport"]')) {
			          const meta = document.createElement('meta');
			          meta.name = 'viewport';
			          meta.content = 'width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no';
			          document.head.appendChild(meta);
			        }
			        
			        // 添加样式确保内容不被压缩
			        const style = document.createElement('style');
			        style.textContent = 'body { min-height: 100vh; } .reserve-content, .reserve-webview-bottom { transition: transform 0.3s ease; }';
			        document.head.appendChild(style);
			        
			        // 防止iOS键盘弹出时页面闪烁
			        document.addEventListener('focusin', function(e) {
			          if (e.target.tagName === 'INPUT' || e.target.tagName === 'TEXTAREA') {
			            // 阻止默认的滚动行为
			            e.preventDefault();
			            document.body.scrollTop = 0;
			            document.documentElement.scrollTop = 0;
			          }
			        }, true);
			        
			        // 监听键盘收起事件
			        document.addEventListener('focusout', function(e) {
			          if (e.target.tagName === 'INPUT' || e.target.tagName === 'TEXTAREA') {
			            // 重置页面状态
			            document.body.scrollTop = 0;
			            document.documentElement.scrollTop = 0;
			            document.body.setAttribute('data-keyboard', 'hidden');
			          }
			        }, true);
			      `);

          if (isInit) {
            this.initKeyboardHeight();
          }
        }
      }, 500);
    },
    initKeyboardHeight() {
      // 记录上一次键盘高度，避免频繁更新导致闪烁
      let lastKeyboardHeight = 0;
      uni.onKeyboardHeightChange((res) => {
        // 如果高度没有变化，不做处理
        if (lastKeyboardHeight === res.height) return;
        lastKeyboardHeight = res.height;
        const newHeight = this.isIos ? 120 : 65;
        // 当键盘弹出时，调整WebView
        if (wv) {
          if (res.height > 0) {
            setTimeout(() => {
              // 键盘弹出时
              wv.evalJS(`
								  document.body.scrollTop = 0;
								  document.documentElement.scrollTop = 0;
								  requestAnimationFrame(() => {
								    const inputContainer = document.querySelector('.reserve-webview-bottom');
								    const reserveContent = document.querySelector('.reserve-content');
								    if (inputContainer) {
								      inputContainer.style.transform = 'translate3d(0, -${
                        res.height - newHeight
                      }px, 0)';
								      reserveContent.style.transform = 'translate3d(0, -${
                        res.height - newHeight
                      }px, 0)';
								      document.body.setAttribute('data-keyboard', 'visible');
								    }
								  });
								`);
            }, 50);
          } else {
            setTimeout(() => {
              // 键盘收起时，完全重置页面状态
              wv.evalJS(`
								  requestAnimationFrame(() => {
								    const inputContainer = document.querySelector('.reserve-webview-bottom');
								    const reserveContent = document.querySelector('.reserve-content');
								    if (inputContainer) {
								      inputContainer.style.transform = 'translate3d(0, 0, 0)';
								      reserveContent.style.transform = 'translate3d(0, 0, 0)';
								      document.body.setAttribute('data-keyboard', 'hidden');
								      
								      // 强制重新计算布局
								      document.body.style.height = '100vh';
								      setTimeout(() => {
								        document.body.style.height = '';
								      }, 50);
								    }
								  });
								`);
            }, 50);
          }
        }
      });
    },
    message(e) {
      //接收H5发送给app的消息
      // e.detail.data即为H5中uni.webView.postMessage()的data的内容
      let mesg = e.detail.data[0];
      // console.log("mesg", mesg.action)
      if (mesg.action == "开始录音") {
        this.startVoice();
      }
      if (mesg.action == "结束录音") {
        this.endVoice();
      }
      if (mesg.action == "开始会议记录") {
        this.meetingLv = mesg.data;
        this.startMeeting();
      }
      if (mesg.action == "结束会议记录") {
        this.endMeeting();
      }
      if (mesg.action == "视频通话") {
        this.video();
      }
      if (mesg.action == "结束通话") {
        this.close();
      }
      if (mesg.action == "信息") {
        this.showinfo();
      }
      if (mesg.action == "日程提醒") {
        this.scheduleobj = mesg.data;
        // console.log("mesgdata:", mesg.data)
        this.getplatform();
      }
      if (mesg.action == "clientid") {
        this.clientid = mesg.data;
        // console.log("baseurl:", mesg.data)
      }
      if (mesg.action == "baseurl") {
        this.setbaseurl = mesg.data;
        // console.log("baseurl:", uni.getStorageSync("baseurl"))
      }
      if (mesg.action == "食运") {
        this.showFoodLuck();
      }
      if (mesg.action == "组局") {
        this.showformgroup();
      }
      //分享图片
      if (mesg.action == "sharePoster") {
        this.onSharePoster(mesg.data);
      }
    },
    // vue的method里编写如下代码
    async requestAndroidPermission() {
      if (
        (await permision.requestAndroidPermission(
          "android.permission.READ_CALENDAR"
        )) != 1 ||
        (await permision.requestAndroidPermission(
          "android.permission.WRITE_CALENDAR"
        )) != 1
      ) {
        uni.showModal({
          content: "未获得日历授权",
          showCancel: false,
        });
        return false;
      }
      return true;
    },
    // 获取手机平台
    getplatform() {
      //判断是否获取权限
      if (!this.requestAndroidPermission()) return;
      // console.log(+ new Date('2022-08-03 15:40:00'));
      uni.getSystemInfo({
        success: (res) => {
          if (res.platform === "android") {
            this.addEventToCalendar();
          }
        },
      });
    },
    // 主入口函数
    async addEventToCalendar() {
      // 获取日历ID
      const calendarId = await this.getCalendarId();
      // console.log("calendarId:", calendarId);
      if (!calendarId) {
        uni.showToast({
          title: "未找到可用日历账户",
          icon: "none",
        });
        return;
      }

      // 创建日历事件
      const eventData = {
        title:
          "私小理日程提醒:" +
          this.scheduleobj.runtime_data +
          "提醒您" +
          this.scheduleobj.title,
        description: this.scheduleobj.title,
        location: "",
        startTime: this.scheduleobj.runtime * 1000, // 当前时间
        endTime: this.scheduleobj.runtime * 1000, // 2小时后
        timeZone: "Asia/Shanghai",
        reminderMinutes: 5, // 提前5分钟提醒
      };

      // console.log("eventData:", eventData);

      // 插入事件
      const result = await this.insertCalendarEvent(calendarId, eventData);
      if (result) {
        uni.showToast({
          title: "同步系统日历",
          icon: "success",
        });
      } else {
        uni.showToast({
          title: "添加失败，请重试",
          icon: "none",
        });
      }
    },
    // 请求日历权限
    requestCalendarPermission() {
      return new Promise((resolve) => {
        plus.android.requestPermissions(
          ["WRITE_CALENDAR"],
          (e) => {
            resolve(e.denied.length === 0 && e.deniedAlways.length === 0);
          },
          (err) => {
            console.error("权限请求错误:", err);
            resolve(false);
          }
        );
      });
    },
    // 获取日历账户ID
    getCalendarId() {
      return new Promise((resolve) => {
        try {
          // 导入必要的Android类
          const CalendarContract = plus.android.importClass(
            "android.provider.CalendarContract"
          );
          const ContentResolver = plus.android.importClass(
            "android.content.ContentResolver"
          );
          const Uri = plus.android.importClass("android.net.Uri");

          const main = plus.android.runtimeMainActivity();

          // 获取CONTENT_URI
          const uri = CalendarContract.Calendars.CONTENT_URI;

          // 投影列
          const projection = [
            CalendarContract.Calendars._ID,
            CalendarContract.Calendars.NAME,
            CalendarContract.Calendars.ACCOUNT_NAME,
          ];

          // 构建查询条件
          const selection = `${CalendarContract.Calendars.VISIBLE} = ? AND ${CalendarContract.Calendars.CALENDAR_ACCESS_LEVEL} >= ?`;
          const selectionArgs = [
            "1",
            CalendarContract.Calendars.CAL_ACCESS_CONTRIBUTOR.toString(),
          ];

          // 获取ContentResolver
          const contentResolver = main.getContentResolver();

          // 使用plus.android.invoke调用query方法
          const cursor = plus.android.invoke(
            contentResolver,
            "query",
            uri,
            projection,
            selection,
            selectionArgs,
            null
          );

          if (cursor) {
            // 使用plus.android.invoke调用cursor方法
            if (plus.android.invoke(cursor, "moveToFirst")) {
              const idIndex = plus.android.invoke(
                cursor,
                "getColumnIndex",
                CalendarContract.Calendars._ID
              );
              const calendarId = plus.android.invoke(
                cursor,
                "getString",
                idIndex
              );
              plus.android.invoke(cursor, "close");
              resolve(calendarId);
            } else {
              plus.android.invoke(cursor, "close");
              resolve(null);
            }
          } else {
            resolve(null);
          }
        } catch (e) {
          console.error("获取日历ID错误:", e);
          resolve(null);
        }
      });
    },
    // 插入日历事件
    async insertCalendarEvent(calendarId, eventData) {
      try {
        const main = plus.android.runtimeMainActivity();
        const Events = plus.android.importClass(
          "android.provider.CalendarContract$Events"
        );
        const ContentValues = plus.android.importClass(
          "android.content.ContentValues"
        );
        const ContentUris = plus.android.importClass(
          "android.content.ContentUris"
        );

        // 创建事件内容
        const values = new ContentValues();
        values.put(Events.CALENDAR_ID, calendarId);
        values.put(Events.TITLE, eventData.title);
        values.put(Events.DESCRIPTION, eventData.description || "");
        values.put(Events.EVENT_LOCATION, eventData.location || "");
        values.put(Events.DTSTART, eventData.startTime);
        values.put(Events.DTEND, eventData.endTime);
        values.put(
          Events.EVENT_TIMEZONE,
          eventData.timeZone || "Asia/Shanghai"
        );
        values.put(Events.HAS_ALARM, 1); // 启用提醒

        // var values = new ContentValues();
        // values.put('event_id', id);
        // values.put('minutes', '5');
        // values.put('method', '1');

        // 尝试多种可能的URI（兼容不同厂商）
        const uris = [
          "content://com.android.calendar/events",
          "content://org.android.calendar/events",
          "content://calendar/events",
          "content://com.htc.calendar/events", // HTC设备
          "content://com.sonyericsson.calendar/events", // 索尼设备
        ];

        let eventId = null;
        let usedUri = null;

        // 尝试插入事件
        for (const uriStr of uris) {
          try {
            const Uri = plus.android.importClass("android.net.Uri");
            const uri = Uri.parse(uriStr);

            // 插入事件
            const result = plus.android.invoke(
              main.getContentResolver(),
              "insert",
              uri,
              values
            );

            if (result) {
              // 从返回的URI中提取事件ID
              eventId = ContentUris.parseId(result);
              usedUri = uriStr;
              break;
            }
          } catch (e) {
            // console.log(`URI ${uriStr} 失败: ${e.message}`);
          }
        }

        if (!eventId) {
          return false;
        }

        // 添加提醒（提前5分钟）
        await this.addEventReminder(
          eventId,
          eventData.reminderMinutes,
          usedUri
        );

        return true;
      } catch (e) {
        console.error("插入日历事件错误:", e);
        return false;
      }
    },
    // 添加闹铃提醒
    async addEventReminder(eventId, minutesBefore, usedUri) {
      try {
        const main = plus.android.runtimeMainActivity();
        const Reminders = plus.android.importClass(
          "android.provider.CalendarContract$Reminders"
        );
        const ContentValues = plus.android.importClass(
          "android.content.ContentValues"
        );
        const Uri = plus.android.importClass("android.net.Uri");

        // 构建提醒URI（基于事件URI）
        const reminderUriStr = usedUri.replace("events", "reminders");
        const reminderUri = Uri.parse(reminderUriStr);

        // 创建提醒内容 - 明确设置为闹铃提醒
        const reminderValues = new ContentValues();
        reminderValues.put(Reminders.EVENT_ID, eventId);
        reminderValues.put(Reminders.MINUTES, minutesBefore);
        reminderValues.put(Reminders.METHOD, Reminders.METHOD_ALERT); // 关键：设置为闹铃提醒

        // 插入提醒
        const result = plus.android.invoke(
          main.getContentResolver(),
          "insert",
          reminderUri,
          reminderValues
        );

        if (result) {
          console.log(`闹铃提醒设置成功：提前${minutesBefore}分钟`);
          return true;
        }
        return false;
      } catch (e) {
        console.error("添加闹铃提醒失败:", e);
        return false;
      }
    },
    showFoodLuck() {
      uni.navigateTo({
        url: "/activityPages/foodLuck",
      });
    },
    showformgroup() {
      uni.navigateTo({
        url: "/activityPages/formgroup",
      });
    },
    showinfo() {
      uni.navigateTo({
        url: "/circlePages/group?showUid=" + this.zsid,
      });
    },
// 分享海报按钮事件
    hideSharePoster() {
      this.isSharePosterVisible = false;
    },
    async onSharePoster(code) {
      code = code ? code : this.userInfo.invite_code;
      console.log("code", code);
      try {
        const posterPath = await this.drawPosterWithInviteCode(code);
        // 这里调用原有的系统分享方式
        uni.shareWithSystem({
          type: "image",
          imageUrl: posterPath, // 用canvas生成的新图片
          success: () => {
            uni.showToast({
              title: "分享成功",
              icon: "none",
            });
            this.$emit("cancel");
          },
          fail: () => {
            uni.showToast({
              title: "分享失败",
              icon: "none",
            });
          },
        });
      } catch (e) {
        // 错误已在上面处理
      }
      this.showSharePoster = false;
    },
    // 生成带邀请码的海报图片
    drawPosterWithInviteCode(code) {
      return new Promise((resolve, reject) => {
        uni.getImageInfo({
          src: "/static/shara720.png",
          success: (bgRes) => {
            const ctx = uni.createCanvasContext("posterCanvas", this);
            ctx.drawImage(bgRes.path, 0, 0, 600, 1067);

            // 只绘制邀请码，白色，居中
            ctx.setFontSize(30);
            ctx.setFillStyle("#FFFFFF");
            ctx.setTextAlign("center");
            ctx.setFontFamily && ctx.setFontFamily("Arial");
            ctx.fillText(
              "邀请码：" + code,
              300,
              1020 // 纵坐标下移，比如1030，具体可多试几次
            );
            ctx.draw(false, () => {
              uni.canvasToTempFilePath(
                {
                  canvasId: "posterCanvas",
                  width: 600,
                  height: 1067,
                  destWidth: 600,
                  destHeight: 1067,
                  success: (res) => {
                    resolve(res.tempFilePath);
                  },
                  fail: (err) => {
                    uni.showToast({
                      title: "生成海报失败",
                      icon: "none",
                    });
                    reject(err);
                  },
                },
                this
              );
            });
          },
          fail: (err) => {
            uni.showToast({
              title: "加载背景失败",
              icon: "none",
            });
            reject(err);
          },
        });
      });
    },
	islogin() {
      if (this.loginToken == "") {
        // uni.navigateTo({
        // 	url: '/minePages/login'
        // })
      }
    },
    acceptData(data) {
      // console.log("data:", data)
    },
    initRecorder() {
      this.startVoice();
      // 监听麦克风音量的变化
      recorderManager.onVoiceChangeStart(function (res) {
        // console.log("开始说话", res)
        // 当声音变化开始时，可以认为用户开始说话，开始录音
        this.startVoice();
      });
      // 监听声音变化结束事件
      recorderManager.onVoiceChangeEnd(function (res) {
        // console.log("说话结束", res)
        // 当声音变化结束时，停止录音
        this.endVoice();
      });
      // 开始录音，需要在用户授权麦克风权限后调用
      // console.log('isSpeaking:',this.isSpeaking);
    },
    // 发送数据到webview
    sendDataToWebView(ask, type) {
      let webview = null;
      if (uni.getCurrentPages().length > 0) {
        const currentPage =
          uni.getCurrentPages()[uni.getCurrentPages().length - 1];
        if (currentPage.route.indexOf("webview") !== -1) {
          webview = currentPage.$scope.$getAppWebview();
        }
      }

      if (webview) {
        webview.postMessage({
          data: ask,
        });
      }
    },
    evalJsInWebView() {
      currentWebview = this.$scope.$getAppWebview(); //获取当前页面的webvie
      setTimeout(function () {
        this.wv = currentWebview.children()[0]; //获取当前web-view
      }, 200); //如页面初始化调用需要写延迟
      if (uni.getStorageSync("makeNewAvatar")) {
        // console.log('makeNewAvatar:',uni.getStorageSync("makeNewAvatar"));
        let makeNewAvatar = uni.getStorageSync("makeNewAvatar");
        // console.log("role:", makeNewAvatar.role)
        // console.log("timbre:", makeNewAvatar.timbre)
        this.wv.evalJsInWebView(
          "document.dispatchEvent(new CustomEvent('getAppMsg',{detail: {role:" +
            makeNewAvatar.role +
            "}}))"
        );
        this.wv.evalJsInWebView(
          "document.dispatchEvent(new CustomEvent('getAppMsg',{detail: {timbre:" +
            makeNewAvatar.timbre +
            "}}))"
        );
      }
    },
    openLocation() {
      uni.openLocation({
        longitude: 113.3298396012573,
        latitude: 22.961803525530176,
        name: "祈福新村",
        address: "祈福新村",
      });
    },
    // 跳转
    tn(e) {
      uni.navigateTo({
        url: e,
      });
    },
    // 初始化滚动
    initScrollBar() {
      setTimeout(() => {
        this.scrollViewId = "";
        setTimeout(() => {
          this.scrollViewId = "bottom";
          setTimeout(() => {
            this.scrollViewId = "";
          }, 100);
        }, 100);
      }, 100);
    },
    // 监听输入聚焦
    inputFocus(e) {
      this.setScrollHeight(e.detail.height);
      this.initScrollBar();

      uni.onKeyboardHeightChange((res) => {
        this.setScrollHeight(res.height);
        this.initScrollBar();
      });
    },
    // 设置scroll的高度
    setScrollHeight(descHeight = 0) {
      // #ifdef MP-WEIXIN
      this.scrollHeight = `calc(100vh - 110rpx - ${descHeight}px)`;
      // #endif
      // #ifdef APP-PLUS
      this.scrollHeight = `calc(100vh - 110upx - ${descHeight}px)`;
      // #endif
      // #ifdef H5
      this.scrollHeight = `calc(100vh - 110upx - 88rpx - ${descHeight}px)`;
      // #endif
    },
    // 切换选择
    togglePicker(height = 0, type = "") {
      this.showEmoji = false;
      this.showFile = false;
      let status = height > 0 ? true : false;

      switch (type) {
        case "emoji":
          this.showEmoji = status;
          break;
        case "file":
          this.showFile = status;
          break;
      }

      setTimeout(() => {
        this.setScrollHeight(height);
        this.initScrollBar();
      }, 50);
    },
    // 切换语音与编辑
    toggleEdit(bool) {
      this.isEdit = bool;
      this.isFocus = bool;
      this.setScrollHeight(0);
    },
    // 开始录音
    startVoice() {
      // console.log("开始录音")
      // this.showVoice = true
      // this.recorderManager.start()
      // const recorderManager = uni.getRecorderManager()
      const options = {
        //采样率
        sampleRate: 16000,
        //录音通道数
        numberOfChannels: 1,
        //编码码率
        encodeBitRate: 16,
        //音频格式
        format: "mp3",
      };
      recorderManager.start(options);
      // this.record.start().then(() => {
      //   this.recording = true;
      // });
    },
    // 结束录音
    endVoice() {
      // console.log("结束录音")
      // this.showVoice = false
      // const recorderManager = uni.getRecorderManager()
      recorderManager.stop();
      // this.record.stopToText({ model: "16k_zh" }).then((text) => {
      //     console.log(text);
      //   }).finally(() => {
      //     this.recording = false;
      //   });
    },
    // 开始会议
    startMeeting() {
      console.log("开始会议");
      this.isMeeting = true;
      // this.showVoice = true
      // this.recorderManager.start()
      // const recorderManager = uni.getRecorderManager()
      const options = {
        duration: 7200000,
        //采样率
        sampleRate: 16000,
        //录音通道数
        numberOfChannels: 1,
        //编码码率
        encodeBitRate: 16,
        //音频格式
        format: "mp3",
      };
      recorderManager.start(options);
      // this.record.start().then(() => {
      //   this.recording = true;
      // });
    },
    // 结束会议
    endMeeting() {
    //   console.log("结束会议");
      // this.showVoice = false
      // const recorderManager = uni.getRecorderManager()
      recorderManager.stop();
      // this.record.stopToText({ model: "16k_zh" }).then((text) => {
      //     console.log(text);
      //   }).finally(() => {
      //     this.recording = false;
      //   });
    },
    // 上传
    upload(filePath) {
      // this.$util.loading('上传中')
      uni.uploadFile({
        url: "https://ocr.luyanshidai.com:6501/api/core/user/upload",
        name: "file",
        filePath,
        formData: {
          userId: "168168168",
        },
        success: (res) => {
          uni.hideLoading();
          let data = JSON.parse(res.data);
          // this.pushMessage(data.data, 'voice')
        },
        fail: (err) => {
          uni.hideLoading();
        },
      });
    },
    // 播放录音
    playVoice(item) {
      // if(this.voicePlayingId){
      // 	this.voicePlayingId = ''
      // }else{
      // 	this.voicePlayingId = item.id
      // 	innerAudioContext.src = item.content
      // 	innerAudioContext.play()
      // }
    },
    // 长按
    longPress(msg) {
      // this.record.start().then(() => {
      //   recording = true;
      // });
      // this.record.stopToText("16k_zh").then((text) => {
      //     console.log(text);
      //   }).finally(() => {
      //     recording = false;
      //   });
      // let data = {
      // 	type: 'single',
      // 	source: this.fromUserId,
      // 	dest: this.toUserId,
      // 	timestamp: new Date().getTime(),
      // 	msg: {
      // 		id: msg.id,
      // 		fromUserId: msg.fromUserId,
      // 		toUserId: msg.toUserId,
      // 		type: 'cancel',
      // 		content: msg.content
      // 	}
      // }
      // uni.sendSocketMessage({
      // 	data: JSON.stringify(data),
      // 	success: res=>{
      // 		// 撤销本地消息
      // 		this.list = this.list.map(item=>{
      // 			item.type = item.id == msg.id ? 'cancel' : item.type
      // 			return item
      // 		})
      // 	}
      // })
    },
    // 获取位置
    getLocation() {
      uni.getLocation({
        success: (res) => {
          let { latitude, longitude } = res;
          uni.chooseLocation({
            latitude,
            longitude,
            success: (chooseRes) => {
              this.pushMessage(JSON.stringify(chooseRes), "map");
            },
          });
        },
      });
    },
    // 打开位置
    openLocation(content) {
      let { latitude, longitude } = JSON.parse(content);
      uni.openLocation({
        latitude,
        longitude,
      });
    },
    // 发送图片
    uploadImage(sourceType = ["album"]) {
      uni.chooseImage({
        sourceType,
        success: (chooseImageRes) => {
          const tempFilePaths = chooseImageRes.tempFilePaths;

          tempFilePaths.forEach((temp) => {
            this.$util.loading("上传中");
            uni.uploadFile({
              url: this.$api.upload,
              filePath: temp,
              formData: {
                userId: this.fromUserId,
              },
              name: "file",
              header: this.$util.getHeader(),
              success: (uploadRes) => {
                uni.hideLoading();
                let data = JSON.parse(uploadRes.data);
                this.pushMessage(data.data, "image");
              },
              fail: (err) => {
                uni.hideLoading();
              },
            });
          });
        },
      });
    },
    // 视频通话
    video() {
      this.isVideo = true;
      // console.log("isVideo:", this.isVideo)
      // this.nextCas.changeCamera({ x: 0, y: 1.65, z: 0.58 },{ x: 0, y: 1.61, z: -0.45 },100);
    },
    close() {
      // this.nextCas.changeCamera({ x: 0, y: 1.65, z: 1.6 },{ x: 0, y: 1.61, z: 1.2 },500);
      this.isVideo = false;
      // console.log("isVideo:", this.isVideo)
    },
    // 发送消息
    send() {
      // this.nextCas.changeCamera({ x: 0, y: 1.65, z: 1.6 },{ x: 0, y: 1.61, z: 1.2 },500);
      uni.setStorageSync("token", this.tokenInfo);
      let date = {
        query: this.content,
        user_uuid: "0001",
        role: "LuXun",
      };
      this.$Request.postJson("/api/role/single", date).then((res) => {
        let date2 = {
          text: res,
        };
        this.$Request.postT("/api/core/user/tts", date2).then((res2) => {
          // this.$Request.postJsonH("/api/v1/tts", date2).then((res2) => {
          // console.log(res2);
          // res2.data.ttsInfo.replace(/\\/g, '\');
          var obj = JSON.parse(res2.data.ttsInfo);
          // console.log(obj);
          // const arrayBuffer = uni.base64ToArrayBuffer(obj.data);
          // const innerAudioContext = wx.createInnerAudioContext();
          // innerAudioContext.src = obj.data;
          // const arrayBuffer = uni.base64ToArrayBuffer('data:audio/mp3;base64,'+ obj.data);
          // innerAudioContext.play();
          // const arrayBuffer = innerAudioContext.src;
          // console.log(arrayBuffer);
          // this.nextCas.speakByAudio(obj.data, {
          //   onEnd: () => {
          //     console.log("结束");
          //   },
          //   onStart: () => {
          //     console.log("开始");
          //   },
          // });
        });
        // console.log(res);
        // this.nextCas.speak(res, {
        //   onEnd: () => {
        //     console.log("onEnd");
        //   },
        //   onStart: () => {
        //     console.log("onStart");
        //   },
        // });
      });
      // this.nextCas.ask(this.content);
      this.content = "";
      this.pushMessage(this.content, "text", () => {
        this.content = "";
      });
    },
    // 推送消息
    pushMessage(content, type = "text", cb = () => {}) {
      // 组合消息体：需要保存在本地数据库的数据
      let msgData = {
        fromUserId: this.fromUserId,
        userFace: uni.getStorageSync("userFace"),
        toUserId: this.toUserId,
        type,
        content,
      };

      // 本地保存
      // uni.request({
      // 	method: 'POST',
      // 	url: this.$api.addSingleMsg,
      // 	data: msgData,
      // 	header: this.$util.getHeader(),
      // 	success: res=>{
      // 		if(res.data.code){
      // 			return this.$util.toast(res.data.code)
      // 		}
      // 		let msgId = res.data.data

      // 		// 判断是否为非文本
      // 		if(!['text', 'map'].includes(type)){
      // 			msgData.content = this.$api.staticPath + msgData.content
      // 		}

      // 		// 发送单聊消息
      // 		this.$xbcim.sendSingle({
      // 			content: msgData.content,
      // 			msgType: type,
      // 			source: this.fromUserId,
      // 			target: this.toUserId,
      // 			extra: {
      // 				id: msgId,
      // 				userFace: uni.getStorageSync('userFace')
      // 			}
      // 		})

      // 		// 加入信息
      // 		this.list.push({
      // 			source: this.fromUserId,
      // 			target: this.toUserId,
      // 			content: msgData.content,
      // 			userFace: uni.getStorageSync('userFace'),
      // 			type: 'single',
      // 			msgType: type
      // 		})

      // 		// 初始化滚动条
      // 		this.initScrollBar()
      // 		cb ? cb() : this.togglePicker(0, 'file')
      // 	}
      // })
    },
  },
};
</script>

<script module="renderScript" lang="renderjs">
export default {
	methods: {
		onChange(newValue, oldValue, ownerInstance) {
			const url = 'https://human.cycyai.com:8881/work1091/imagehuman-ready-to-talk';
			let eventData = '';
			let myframe = 0;
			let prompt = '';
			let end = 0;
			if (newValue.url != '') {
				fetch(newValue.url, {
						method: 'POST',
						headers: {
							'Content-Type': 'application/json'
						},
						body: JSON.stringify(newValue.myDate) // 将请求体转换为 JSON 字符串
					})
					.then(response => response.json())
					.then(data => {
						if (data.status === 'success') {
							ownerInstance.callMethod('acceptData', {
								type: 'success'
							});
						} else {
							ownerInstance.callMethod('acceptData', {
								type: 'error',
								uuid: newValue.myDate.uuid
							});
						}
					})
					.catch(error => {
						ownerInstance.callMethod('acceptData', {
							type: 'error',
							uuid: null
						});
					});

			} else {
				ownerInstance.callMethod('acceptData', {
					type: 'star'
				});
			}
		},
	}
}
</script>

<style lang="scss" scoped>
.template-reserve {
  position: fixed;
  top: 0;
  left: 0;
  width: 100vw;
  height: 100vh;
}

/* 胶囊*/
.tn-custom-nav-bar__back {
  width: 100%;
  height: 100%;
  position: relative;
  display: flex;
  justify-content: space-evenly;
  align-items: center;
  box-sizing: border-box;
  background-color: rgba(0, 0, 0, 0.15);
  border-radius: 1000rpx;
  border: 1rpx solid rgba(255, 255, 255, 0.5);
  color: #ffffff;
  font-size: 18px;

  .icon {
    display: block;
    flex: 1;
    margin: auto;
    text-align: center;
  }

  &:before {
    content: " ";
    width: 1rpx;
    height: 110%;
    position: absolute;
    top: 22.5%;
    left: 0;
    right: 0;
    margin: auto;
    transform: scale(0.5);
    transform-origin: 0 0;
    pointer-events: none;
    box-sizing: border-box;
    opacity: 0.7;
    background-color: #ffffff;
  }
}

page {
  margin: 0;
  padding: 0;
  background: #262626;
}

.ring {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 150px;
  height: 150px;
  background: transparent;
  border: 3px solid #3c3c3c;
  border-radius: 50%;
  text-align: center;
  line-height: 150px;
  font-family: sans-serif;
  font-size: 20px;
  color: #fff000;
  letter-spacing: 4px;
  text-transform: uppercase;
  text-shadow: 0 0 10px #fff000;
  box-shadow: 0 0 20px rgba(0, 0, 0, 0.5);

  text {
    display: block;
    position: absolute;
    top: calc(50% - 2px);
    left: 50%;
    width: 50%;
    height: 4px;
    background: transparent;
    transform-origin: left;
    animation: animate 2s linear infinite;
  }

  text:before {
    content: "";
    position: absolute;
    width: 16px;
    height: 16px;
    border-radius: 50%;
    background: #fff000;
    top: -6px;
    right: -8px;
    box-shadow: 0 0 20px #fff000;
  }
}

.ring:before {
  content: "";
  position: absolute;
  top: -3px;
  left: -3px;
  width: 100%;
  height: 100%;
  border: 3px solid transparent;
  border-top: 3px solid #fff000;
  border-right: 3px solid #fff000;
  border-radius: 50%;
  animation: animateC 2s linear infinite;
}

@keyframes animateC {
  0% {
    transform: rotate(0deg);
  }

  100% {
    transform: rotate(360deg);
  }
}

@keyframes animate {
  0% {
    transform: rotate(45deg);
  }

  100% {
    transform: rotate(405deg);
  }
}

/* 用户头像 start */
.logo-image2 {
  width: 110rpx;
  height: 110rpx;
  position: relative;
}

.logo-pic2 {
  background-size: cover;
  background-repeat: no-repeat;
  // background-attachment:fixed;
  background-position: top;
  border: 8rpx solid rgba(255, 255, 255, 0.05);
  box-shadow: 0rpx 0rpx 80rpx 0rpx rgba(0, 0, 0, 0.15);
  border-radius: 50%;
  overflow: hidden;
  // background-color: #FFFFFF;
}

/* 内容*/
.reserve {
  position: relative;
  z-index: 99;
}

.reserve-content {
  background-color: rgba(255, 255, 255, 0.7);
  border-radius: 30rpx;
}

/* 标签 */
.blogger {
  &__item {
    padding: 30rpx;
  }

  &__desc {
    line-height: 55rpx;

    &__label {
      padding: 0 20rpx;
      margin: 0rpx 18rpx 0 0;

      &--prefix {
        color: #00ffc8;
        padding-right: 10rpx;
      }
    }
  }
}

/* 文字截取*/
.clamp-text-1 {
  -webkit-line-clamp: 1;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  text-overflow: ellipsis;
  overflow: hidden;
}

.clamp-text-2 {
  -webkit-line-clamp: 2;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  text-overflow: ellipsis;
  overflow: hidden;
}

/* 毛玻璃*/
.dd-glass {
  width: 100%;
  backdrop-filter: blur(20rpx);
  -webkit-backdrop-filter: blur(20rpx);
}

/* 毛玻璃*/
.dd-glass2 {
  // width: 100%;
  backdrop-filter: blur(8rpx);
  -webkit-backdrop-filter: blur(8rpx);
}

/* 用户头像 start */
.user-image {
  width: 70rpx;
  height: 70rpx;
  position: relative;
}

.user-pic {
  background-size: cover;
  background-repeat: no-repeat;
  // background-attachment:fixed;
  background-position: top;
  border-radius: 100rpx;
  overflow: hidden;
  background-color: #ffffff;
}

/* 底部悬浮按钮 start*/
.tn-tabbar-height {
  min-height: 120rpx;
  height: calc(140rpx + env(safe-area-inset-bottom) / 2);
}

.tn-footerfixed {
  position: fixed;
  background-color: rgba(255, 255, 255, 0.5);
  box-shadow: 0rpx 0rpx 30rpx 0rpx rgba(0, 0, 0, 0.07);
  bottom: 0;
  width: 100%;
  transition: all 0.25s ease-out;
  z-index: 100;
}

/* 相册 start*/
.slideshow {
  top: 0;
  position: fixed;
  width: 100vw;
  height: 100vh;
  overflow: hidden;
  z-index: 0;
}

.slideshow-image {
  position: absolute;
  width: 100%;
  height: 100%;
  background: no-repeat 50% 50%;
  background-size: cover;
  -webkit-animation-name: kenburns;
  animation-name: kenburns;
  -webkit-animation-timing-function: linear;
  animation-timing-function: linear;
  -webkit-animation-iteration-count: infinite;
  animation-iteration-count: infinite;
  -webkit-animation-duration: 16s;
  animation-duration: 16s;
  opacity: 1;
  transform: scale(1.2);
}

.slideshow-image:nth-child(1) {
  -webkit-animation-name: kenburns-1;
  animation-name: kenburns-1;
  z-index: 3;
}

.slideshow-image:nth-child(2) {
  -webkit-animation-name: kenburns-2;
  animation-name: kenburns-2;
  z-index: 2;
}

.slideshow-image:nth-child(3) {
  -webkit-animation-name: kenburns-3;
  animation-name: kenburns-3;
  z-index: 1;
}

.slideshow-image:nth-child(4) {
  -webkit-animation-name: kenburns-4;
  animation-name: kenburns-4;
  z-index: 0;
}

@-webkit-keyframes kenburns-1 {
  0% {
    opacity: 1;
    transform: scale(1.2);
  }

  1.5625% {
    opacity: 1;
  }

  23.4375% {
    opacity: 1;
  }

  26.5625% {
    opacity: 0;
    transform: scale(1);
  }

  100% {
    opacity: 0;
    transform: scale(1.2);
  }

  98.4375% {
    opacity: 0;
    transform: scale(1.2117647059);
  }

  100% {
    opacity: 1;
  }
}

@keyframes kenburns-1 {
  0% {
    opacity: 1;
    transform: scale(1.2);
  }

  1.5625% {
    opacity: 1;
  }

  23.4375% {
    opacity: 1;
  }

  26.5625% {
    opacity: 0;
    transform: scale(1);
  }

  100% {
    opacity: 0;
    transform: scale(1.2);
  }

  98.4375% {
    opacity: 0;
    transform: scale(1.2117647059);
  }

  100% {
    opacity: 1;
  }
}

@-webkit-keyframes kenburns-2 {
  23.4375% {
    opacity: 1;
    transform: scale(1.2);
  }

  26.5625% {
    opacity: 1;
  }

  48.4375% {
    opacity: 1;
  }

  51.5625% {
    opacity: 0;
    transform: scale(1);
  }

  100% {
    opacity: 0;
    transform: scale(1.2);
  }
}

@keyframes kenburns-2 {
  23.4375% {
    opacity: 1;
    transform: scale(1.2);
  }

  26.5625% {
    opacity: 1;
  }

  48.4375% {
    opacity: 1;
  }

  51.5625% {
    opacity: 0;
    transform: scale(1);
  }

  100% {
    opacity: 0;
    transform: scale(1.2);
  }
}

@-webkit-keyframes kenburns-3 {
  48.4375% {
    opacity: 1;
    transform: scale(1.2);
  }

  51.5625% {
    opacity: 1;
  }

  73.4375% {
    opacity: 1;
  }

  76.5625% {
    opacity: 0;
    transform: scale(1);
  }

  100% {
    opacity: 0;
    transform: scale(1.2);
  }
}

@keyframes kenburns-3 {
  48.4375% {
    opacity: 1;
    transform: scale(1.2);
  }

  51.5625% {
    opacity: 1;
  }

  73.4375% {
    opacity: 1;
  }

  76.5625% {
    opacity: 0;
    transform: scale(1);
  }

  100% {
    opacity: 0;
    transform: scale(1.2);
  }
}

@-webkit-keyframes kenburns-4 {
  73.4375% {
    opacity: 1;
    transform: scale(1.2);
  }

  76.5625% {
    opacity: 1;
  }

  98.4375% {
    opacity: 1;
  }

  100% {
    opacity: 0;
    transform: scale(1);
  }
}

@keyframes kenburns-4 {
  73.4375% {
    opacity: 1;
    transform: scale(1.2);
  }

  76.5625% {
    opacity: 1;
  }

  98.4375% {
    opacity: 1;
  }

  100% {
    opacity: 0;
    transform: scale(1);
  }
}

/* 相册 end*/

.tn-tabbar-height {
  min-height: 100rpx;
  height: calc(120rpx + env(safe-area-inset-bottom) / 2);
}

/* 用户头像 start */
.logo-image {
  width: 80rpx;
  height: 80rpx;
  position: relative;
}

.logo-pic {
  background-size: cover;
  background-repeat: no-repeat;
  // background-attachment:fixed;
  background-position: top;
  // box-shadow: 0rpx 0rpx 80rpx 0rpx rgba(0, 0, 0, 0.15);
  border-radius: 50%;
  // overflow: hidden;
  // background-color: #FFFFFF;
}

.bg-img-cont {
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
  height: 260rpx;
  width: 55vw;
  margin: 10rpx 0 0 0;
  border-radius: 12rpx;
}

/* 聊天*/
.tnchat1 {
  border-style: solid;
  border-width: 71rpx;
  border-image-source: url(https://cdn.nlark.com/yuque/0/2022/png/280373/1656388937089-assets/web-upload/9d92dfd6-3486-4be9-a933-0ae160bdfc86.png);
  border-image-slice: 71 71 71 71 fill;
  border-image-repeat: repeat;
  word-break: break-word;
  width: fit-content;
}

.tnchat2 {
  border-style: solid;
  border-width: 26rpx 43rpx;
  border-image-source: url(https://cdn.nlark.com/yuque/0/2022/png/280373/1656471916508-assets/web-upload/e2305ffa-d1c7-435c-adae-2b3f0bc0da41.png);
  border-image-slice: 26 43 26 43 fill;
  border-image-repeat: repeat;
  word-break: break-word;
  width: fit-content;
}

.tnchat3 {
  border-style: solid;
  border-width: 26rpx 43rpx;
  border-image-source: url(https://cdn.nlark.com/yuque/0/2022/png/280373/1656562395500-assets/web-upload/2662c10c-061b-403d-9289-1165d9ee9e7b.png);
  border-image-slice: 26 43 26 43 fill;
  border-image-repeat: repeat;
  word-break: break-word;
  width: fit-content;
}

.tnchat4 {
  border-style: solid;
  border-width: 26rpx 43rpx;
  border-image-source: url(https://cdn.nlark.com/yuque/0/2022/png/280373/1656562336904-assets/web-upload/ad050d7f-3bdd-4de5-9e67-500f778b20e4.png);
  border-image-slice: 26 43 26 43 fill;
  border-image-repeat: repeat;
  word-break: break-word;
  width: fit-content;
}

.tnchat5 {
  border-style: solid;
  border-width: 26rpx 43rpx;
  border-image-source: url(https://cdn.nlark.com/yuque/0/2022/png/280373/1656562607434-assets/web-upload/cf008270-2a2c-4fac-82b1-b558d8a92230.png);
  border-image-slice: 26 43 26 43 fill;
  border-image-repeat: repeat;
  word-break: break-word;
  width: fit-content;
}

.tnchat6 {
  border-style: solid;
  border-width: 26rpx 43rpx;
  border-image-source: url(https://cdn.nlark.com/yuque/0/2022/png/280373/1656598070402-assets/web-upload/e123a1e3-6235-4d39-81d5-33d221d7a960.png);
  border-image-slice: 26 43 26 43 fill;
  border-image-repeat: repeat;
  word-break: break-word;
  width: fit-content;
}

.tnchat7 {
  border-style: solid;
  border-width: 26rpx 43rpx;
  border-image-source: url(https://cdn.nlark.com/yuque/0/2022/png/280373/1656602660855-assets/web-upload/9c698bba-af80-47bf-9ee4-3a78e0288fc4.png);
  border-image-slice: 26 43 26 43 fill;
  border-image-repeat: repeat;
  word-break: break-word;
  width: fit-content;
}

.container {
  height: 100vh;
  overflow: hidden;
}

/* #ifdef H5 */
.container {
  height: calc(100vh);
}

/* #endif */

.status_bar,
.container,
.header,
.emoji,
.file {
  background-color: #f3f3f3;
}

.header {
  border-bottom: 2upx solid #eee;

  .center {
    font-weight: bold;
  }
}

.map {
  width: 60%;
  height: 300upx;
  background-color: #fff !important;

  &::before {
    border-right: 30upx solid #fff !important;
  }

  .title {
    height: 80upx;
    font-size: 28upx;
    overflow: hidden;
    text-overflow: ellipsis;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
  }

  .box {
    width: 100%;
    height: 170upx;
    margin-top: 10upx;
  }
}

.emoji {
  height: 400upx;
  padding: 0 0 20upx 20upx;
  position: relative;

  .list {
    width: 100%;
    height: 400upx;
    padding: 20upx 0;
    overflow-y: auto;

    .item {
      float: left;
      display: block;
      height: 60upx;
      line-height: 60upx;
      width: calc(100% / 12);
      margin-right: 20upx;
    }
  }
}

.file {
  padding: 30upx 20upx;

  .list {
    overflow: hidden;
    padding-left: 10upx;
    justify-content: flex-start;
  }

  .item {
    float: left;
    width: 110upx;
    height: 110upx;
    border-radius: 10upx;
    margin-right: 40upx;
    background-color: #fff;

    .icon {
      width: 50upx;
    }

    .text {
      font-size: 24upx;
      margin-top: 4upx;
    }
  }
}

.oper {
  width: 100%;
  height: 110upx;
  padding: 0 20upx;
  // border-top: 2upx solid #EEE;
  // border-bottom: 2upx solid #EEE;

  .input {
    height: 68upx;
    line-height: 68upx;
    padding: 0 20upx;
    font-size: 28upx;
    border-radius: 10upx;
    background-color: #fff;
    width: calc(100% - 120upx - 20upx - 40upx - 60upx);
  }

  .icon {
    width: 60upx;
    height: 60upx;
  }

  .btn {
    color: #fff;
    width: 90upx;
    height: 52upx;
    font-size: 24upx;
    line-height: 52upx;
    text-align: center;
    border-radius: 10upx;
    background-color: #2ba245;
  }
}

.scroll {
  overflow-y: auto;
  transition: all 0.1s ease;
  height: calc(100vh - 88upx - 110upx - var(--status-bar-height));

  /* #ifdef MP-WEIXIN */
  height: calc(100vh - 88upx - var(--status-bar-height));
  /* #endif */
  /* #ifdef H5 */
  height: calc(100vh - 88upx - 110upx - var(--status-bar-height));
  /* #endif */

  .item-space {
    height: 30upx;
  }

  .time {
    color: #666;
    font-size: 24upx;
    text-align: center;
    margin-bottom: 20upx;
  }

  .cancel {
    width: 100%;
    height: 40upx;
    text-align: center;
    margin-bottom: 30upx;

    .text {
      color: #999;
      font-size: 24upx;
    }
  }

  .item {
    margin: 0 30upx 30upx;
    align-items: flex-start;
    justify-content: flex-start;

    .face {
      width: 80upx;
      height: 80upx;
      border-radius: 10upx;
    }

    .content {
      color: #000;
      font-size: 32upx;
      min-height: 80upx;
      border-radius: 10upx;
      padding: 20upx 24upx;
      background-color: #fff;
      word-break: break-all;
      word-wrap: break-word;
      max-width: calc(100% - 100upx - 120upx);
      position: relative;

      &::before {
        content: "";
        width: 0;
        height: 0;
        border-right: 30upx solid #fff;
        border-top: 20upx solid transparent;
        border-bottom: 20upx solid transparent;
        position: absolute;
        top: 24upx;
      }

      .voice-icon {
        width: 32upx;
        height: 40upx;
        margin-right: 180upx;
        margin-bottom: -8upx;
      }
    }

    &.left {
      .face {
        margin-right: 30upx;
      }

      .content::before {
        left: -20upx;
      }
    }

    &.right {
      flex-direction: row-reverse;

      .face {
        margin-left: 30upx;
      }

      .content {
        background-color: #a0ea6f;

        &::before {
          right: -20upx;
          transform: rotate(180deg);
          border-right: 30upx solid #a0ea6f;
        }

        .voice-icon {
          margin-right: 0;
          margin-left: 180upx;
          transform: rotate(180deg);
        }
      }
    }
  }

  #bottom {
    height: 0;
  }
}

/* 自定义底部导航栏样式 */
.custom-tabbar {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  flex: 1;
  background-color: #000;
  display: flex;
  align-items: center;
  justify-content: space-around;
  z-index: 1024;
  font-size: 31rpx;
  padding-bottom: env(safe-area-inset-bottom);
  box-sizing: border-box;
}

.tabbar-item {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  transition: all 0.3s ease;
  margin-top: 40rpx;
}

.tabbar-icon {
  margin-bottom: 8rpx;
  transition: transform 0.3s ease;
}

.icon-image {
  display: block;
  transition: all 0.3s ease;
}

.tabbar-text {
  font-size: 22rpx;
  line-height: 1;
  transition: color 0.3s ease;
}

/* iOS和Android适配 */
.webIos .custom-tabbar {
  height: 100rpx;
  padding-bottom: calc(env(safe-area-inset-bottom) + 10rpx);
}

.webAndroid .custom-tabbar {
  height: 194rpx;
  padding-bottom: calc(env(safe-area-inset-bottom) + 5rpx);
}

/* 点击效果 */
.tabbar-item:active {
  opacity: 0.7;
}

.tabbar-item:active .tabbar-icon {
  transform: scale(0.95);
}
</style>
